textview: Fix dnd
authorMatthias Clasen <mclasen@redhat.com>
Sun, 6 Sep 2020 15:48:10 +0000 (11:48 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Sun, 6 Sep 2020 15:48:10 +0000 (11:48 -0400)
When we start a dnd of the selection in the drag-update handler,
set the gesture state to denied. Otherwise, we get more drag-update
signals, and things get really confused, leading to no dnd and
sadness.

gtk/gtktextview.c

index 5b0715befdd7ce2a25beee9bef3cc96ccc826f04..dc8d3c96822a118138e704e35b7b46af1af3e812 100644 (file)
@@ -7188,11 +7188,11 @@ selection_data_free (SelectionData *data)
 
 static gboolean
 drag_gesture_get_text_surface_coords (GtkGestureDrag *gesture,
-                                     GtkTextView    *text_view,
-                                     int            *start_x,
-                                     int            *start_y,
-                                     int            *x,
-                                     int            *y)
+                                      GtkTextView    *text_view,
+                                      int            *start_x,
+                                      int            *start_y,
+                                      int            *x,
+                                      int            *y)
 {
   double sx, sy, ox, oy;
 
@@ -7262,6 +7262,10 @@ gtk_text_view_drag_gesture_update (GtkGestureDrag *gesture,
 
               gtk_text_view_start_selection_dnd (text_view, &iter, event,
                                                  start_x, start_y);
+
+              /* Deny the gesture so we don't get further updates */
+              gtk_gesture_set_state (text_view->priv->drag_gesture,
+                                     GTK_EVENT_SEQUENCE_DENIED);
               return;
             }
           else
@@ -7275,6 +7279,8 @@ gtk_text_view_drag_gesture_update (GtkGestureDrag *gesture,
         return;
     }
 
+  g_assert (data != NULL);
+
   /* Text selection */
   if (data->granularity == SELECT_CHARACTERS)
     {
@@ -7782,6 +7788,14 @@ dnd_finished_cb (GdkDrag     *drag,
   self->priv->drag = NULL;
 }
 
+static void
+dnd_cancel_cb (GdkDrag *drag,
+               GdkDragCancelReason reason,
+               GtkTextView *self)
+{
+  self->priv->drag = NULL;
+}
+
 static void
 gtk_text_view_start_selection_dnd (GtkTextView       *text_view,
                                    const GtkTextIter *iter,
@@ -7808,9 +7822,11 @@ gtk_text_view_start_selection_dnd (GtkTextView       *text_view,
   surface = gdk_event_get_surface (event);
   device = gdk_event_get_device (event);
   drag = gdk_drag_begin (surface, device, content, actions, x, y);
+
   g_object_unref (content);
 
   g_signal_connect (drag, "dnd-finished", G_CALLBACK (dnd_finished_cb), text_view);
+  g_signal_connect (drag, "cancel", G_CALLBACK (dnd_cancel_cb), text_view);
 
   if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
     {